home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / graphics / tiff / libtiff / tif_open.c < prev    next >
C/C++ Source or Header  |  1992-02-13  |  9KB  |  391 lines

  1. #ifndef lint
  2. static char rcsid[] = "$Header: /usr/people/sam/tiff/libtiff/RCS/tif_open.c,v 1.33 92/02/14 13:40:51 sam Exp $";
  3. #endif
  4.  
  5. /*
  6.  * Copyright (c) 1988, 1989, 1990, 1991, 1992 Sam Leffler
  7.  * Copyright (c) 1991, 1992 Silicon Graphics, Inc.
  8.  *
  9.  * Permission to use, copy, modify, distribute, and sell this software and 
  10.  * its documentation for any purpose is hereby granted without fee, provided
  11.  * that (i) the above copyright notices and this permission notice appear in
  12.  * all copies of the software and related documentation, and (ii) the names of
  13.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  14.  * publicity relating to the software without the specific, prior written
  15.  * permission of Sam Leffler and Silicon Graphics.
  16.  * 
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  18.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  19.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  20.  * 
  21.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  22.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  23.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  24.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  25.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  26.  * OF THIS SOFTWARE.
  27.  */
  28.  
  29. /*
  30.  * TIFF Library.
  31.  */
  32. #include "tiffioP.h"
  33. #include "prototypes.h"
  34.  
  35. #if USE_PROTOTYPES
  36. extern    int TIFFDefaultDirectory(TIFF*);
  37. #else
  38. extern    int TIFFDefaultDirectory();
  39. #endif
  40.  
  41. static const long typemask[13] = {
  42.     0,        /* TIFF_NOTYPE */
  43.     0x000000ff,    /* TIFF_BYTE */
  44.     0xffffffff,    /* TIFF_ASCII */
  45.     0x0000ffff,    /* TIFF_SHORT */
  46.     0xffffffff,    /* TIFF_LONG */
  47.     0xffffffff,    /* TIFF_RATIONAL */
  48.     0x000000ff,    /* TIFF_SBYTE */
  49.     0x000000ff,    /* TIFF_UNDEFINED */
  50.     0x0000ffff,    /* TIFF_SSHORT */
  51.     0xffffffff,    /* TIFF_SLONG */
  52.     0xffffffff,    /* TIFF_SRATIONAL */
  53.     0xffffffff,    /* TIFF_FLOAT */
  54.     0xffffffff,    /* TIFF_DOUBLE */
  55. };
  56. static const int bigTypeshift[13] = {
  57.     0,        /* TIFF_NOTYPE */
  58.     24,        /* TIFF_BYTE */
  59.     0,        /* TIFF_ASCII */
  60.     16,        /* TIFF_SHORT */
  61.     0,        /* TIFF_LONG */
  62.     0,        /* TIFF_RATIONAL */
  63.     16,        /* TIFF_SBYTE */
  64.     16,        /* TIFF_UNDEFINED */
  65.     24,        /* TIFF_SSHORT */
  66.     0,        /* TIFF_SLONG */
  67.     0,        /* TIFF_SRATIONAL */
  68.     0,        /* TIFF_FLOAT */
  69.     0,        /* TIFF_DOUBLE */
  70. };
  71. static const int litTypeshift[13] = {
  72.     0,        /* TIFF_NOTYPE */
  73.     0,        /* TIFF_BYTE */
  74.     0,        /* TIFF_ASCII */
  75.     0,        /* TIFF_SHORT */
  76.     0,        /* TIFF_LONG */
  77.     0,        /* TIFF_RATIONAL */
  78.     0,        /* TIFF_SBYTE */
  79.     0,        /* TIFF_UNDEFINED */
  80.     0,        /* TIFF_SSHORT */
  81.     0,        /* TIFF_SLONG */
  82.     0,        /* TIFF_SRATIONAL */
  83.     0,        /* TIFF_FLOAT */
  84.     0,        /* TIFF_DOUBLE */
  85. };
  86.  
  87. /*
  88.  * Initialize the bit fill order, the
  89.  * shift & mask tables, and the byte
  90.  * swapping state according to the file
  91.  * contents and the machine architecture.
  92.  */
  93. static
  94. DECLARE3(TIFFInitOrder, register TIFF*, tif, int, magic, int, bigendian)
  95. {
  96.     /* XXX how can we deduce this dynamically? */
  97.     tif->tif_fillorder = FILLORDER_MSB2LSB;
  98.  
  99.     tif->tif_typemask = typemask;
  100.     if (magic == TIFF_BIGENDIAN) {
  101.         tif->tif_typeshift = bigTypeshift;
  102.         if (!bigendian)
  103.             tif->tif_flags |= TIFF_SWAB;
  104.     } else {
  105.         tif->tif_typeshift = litTypeshift;
  106.         if (bigendian)
  107.             tif->tif_flags |= TIFF_SWAB;
  108.     }
  109. }
  110.  
  111. static int
  112. DECLARE2(getMode, char*, mode, char*, module)
  113. {
  114.     int m = -1;
  115.  
  116.     switch (mode[0]) {
  117.     case 'r':
  118.         m = O_RDONLY;
  119.         if (mode[1] == '+')
  120.             m = O_RDWR;
  121.         break;
  122.     case 'w':
  123.     case 'a':
  124.         m = O_RDWR|O_CREAT;
  125.         if (mode[0] == 'w')
  126.             m |= O_TRUNC;
  127.         break;
  128.     default:
  129.         TIFFError(module, "\"%s\": Bad mode", mode);
  130.         break;
  131.     }
  132.     return (m);
  133. }
  134.  
  135. /*
  136.  * Open a TIFF file for read/writing.
  137.  */
  138. TIFF *
  139. TIFFOpen(name, mode)
  140.     char *name, *mode;
  141. {
  142.     static char module[] = "TIFFOpen";
  143.     int m, fd;
  144.  
  145.     m = getMode(mode, module);
  146.     if (m == -1)
  147.         return ((TIFF *)0);
  148.     fd = TIFFOpenFile(name, m, 0666);
  149.     if (fd < 0) {
  150.         TIFFError(module, "%s: Cannot open", name);
  151.         return ((TIFF *)0);
  152.     }
  153.     return (TIFFFdOpen(fd, name, mode));
  154. }
  155.  
  156. /*
  157.  * Open a TIFF file descriptor for read/writing.
  158.  */
  159. TIFF *
  160. TIFFFdOpen(fd, name, mode)
  161.     int fd;
  162.     char *name, *mode;
  163. {
  164.     static char module[] = "TIFFFdOpen";
  165.     TIFF *tif;
  166.     int m, bigendian;
  167.  
  168.     m = getMode(mode, module);
  169.     if (m == -1)
  170.         goto bad2;
  171.     tif = (TIFF *)malloc(sizeof (TIFF) + strlen(name) + 1);
  172.     if (tif == NULL) {
  173.         TIFFError(module, "%s: Out of memory (TIFF structure)", name);
  174.         goto bad2;
  175.     }
  176.     bzero((char *)tif, sizeof (*tif));
  177.     tif->tif_name = (char *)tif + sizeof (TIFF);
  178.     strcpy(tif->tif_name, name);
  179.     tif->tif_fd = fd;
  180.     tif->tif_mode = m &~ (O_CREAT|O_TRUNC);
  181.     tif->tif_curdir = -1;        /* non-existent directory */
  182.     tif->tif_curoff = 0;
  183.     tif->tif_curstrip = -1;        /* invalid strip */
  184.     tif->tif_row = -1;        /* read/write pre-increment */
  185.     { int one = 1; bigendian = (*(char *)&one == 0); }
  186.     /*
  187.      * Read in TIFF header.
  188.      */
  189.     if (!ReadOK(fd, &tif->tif_header, sizeof (TIFFHeader))) {
  190.         if (tif->tif_mode == O_RDONLY) {
  191.             TIFFError(name, "Cannot read TIFF header");
  192.             goto bad;
  193.         }
  194.         /*
  195.          * Setup header and write.
  196.          */
  197.         tif->tif_header.tiff_magic =  bigendian ?
  198.             TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
  199.         tif->tif_header.tiff_version = TIFF_VERSION;
  200.         tif->tif_header.tiff_diroff = 0;    /* filled in later */
  201.         if (!WriteOK(fd, &tif->tif_header, sizeof (TIFFHeader))) {
  202.             TIFFError(name, "Error writing TIFF header");
  203.             goto bad;
  204.         }
  205.         /*
  206.          * Setup the byte order handling.
  207.          */
  208.         TIFFInitOrder(tif, tif->tif_header.tiff_magic, bigendian);
  209.         /*
  210.          * Setup default directory.
  211.          */
  212.         if (!TIFFDefaultDirectory(tif))
  213.             goto bad;
  214.         tif->tif_diroff = 0;
  215.         return (tif);
  216.     }
  217.     /*
  218.      * Setup the byte order handling.
  219.      */
  220.     if (tif->tif_header.tiff_magic != TIFF_BIGENDIAN &&
  221.         tif->tif_header.tiff_magic != TIFF_LITTLEENDIAN) {
  222.         TIFFError(name,  "Not a TIFF file, bad magic number %d (0x%x)",
  223.             tif->tif_header.tiff_magic,
  224.             tif->tif_header.tiff_magic);
  225.         goto bad;
  226.     }
  227.     TIFFInitOrder(tif, tif->tif_header.tiff_magic, bigendian);
  228.     /*
  229.      * Swap header if required.
  230.      */
  231.     if (tif->tif_flags & TIFF_SWAB) {
  232.         TIFFSwabShort(&tif->tif_header.tiff_version);
  233.         TIFFSwabLong(&tif->tif_header.tiff_diroff);
  234.     }
  235.     /*
  236.      * Now check version (if needed, it's been byte-swapped).
  237.      * Note that this isn't actually a version number, it's a
  238.      * magic number that doesn't change (stupid).
  239.      */
  240.     if (tif->tif_header.tiff_version != TIFF_VERSION) {
  241.         TIFFError(name,
  242.             "Not a TIFF file, bad version number %d (0x%x)",
  243.             tif->tif_header.tiff_version,
  244.             tif->tif_header.tiff_version); 
  245.         goto bad;
  246.     }
  247.     tif->tif_flags |= TIFF_MYBUFFER;
  248.     tif->tif_rawcp = tif->tif_rawdata = 0;
  249.     tif->tif_rawdatasize = 0;
  250.     /*
  251.      * Setup initial directory.
  252.      */
  253.     switch (mode[0]) {
  254.     case 'r':
  255.         tif->tif_nextdiroff = tif->tif_header.tiff_diroff;
  256. #ifdef MMAP_SUPPORT
  257.         if (TIFFMapFileContents(fd, &tif->tif_base, &tif->tif_size))
  258.             tif->tif_flags |= TIFF_MAPPED;
  259. #endif
  260.         if (TIFFReadDirectory(tif)) {
  261.             tif->tif_rawcc = -1;
  262.             tif->tif_flags |= TIFF_BUFFERSETUP;
  263.             return (tif);
  264.         }
  265.         break;
  266.     case 'a':
  267.         /*
  268.          * Don't append to file that has information
  269.          * byte swapped -- we will write data that is
  270.          * in the opposite order.
  271.          */
  272.         if (tif->tif_flags & TIFF_SWAB) {
  273.             TIFFError(name,
  274.         "Cannot append to file that has opposite byte ordering");
  275.             goto bad;
  276.         }
  277.         /*
  278.          * New directories are automatically append
  279.          * to the end of the directory chain when they
  280.          * are written out (see TIFFWriteDirectory).
  281.          */
  282.         if (!TIFFDefaultDirectory(tif))
  283.             goto bad;
  284.         return (tif);
  285.     }
  286. bad:
  287.     tif->tif_mode = O_RDONLY;    /* XXX avoid flush */
  288.     TIFFClose(tif);
  289.     return ((TIFF *)0);
  290. bad2:
  291.     (void) close(fd);
  292.     return ((TIFF *)0);
  293. }
  294.  
  295. TIFFScanlineSize(tif)
  296.     TIFF *tif;
  297. {
  298.     TIFFDirectory *td = &tif->tif_dir;
  299.     long scanline;
  300.     
  301.     scanline = td->td_bitspersample * td->td_imagewidth;
  302.     if (td->td_planarconfig == PLANARCONFIG_CONTIG)
  303.         scanline *= td->td_samplesperpixel;
  304.     return (howmany(scanline, 8));
  305. }
  306.  
  307. /*
  308.  * Query functions to access private data.
  309.  */
  310.  
  311. /*
  312.  * Return open file's name.
  313.  */
  314. char *
  315. TIFFFileName(tif)
  316.     TIFF *tif;
  317. {
  318.     return (tif->tif_name);
  319. }
  320.  
  321. /*
  322.  * Return open file's I/O descriptor.
  323.  */
  324. int
  325. TIFFFileno(tif)
  326.     TIFF *tif;
  327. {
  328.     return (tif->tif_fd);
  329. }
  330.  
  331. /*
  332.  * Return read/write mode.
  333.  */
  334. int
  335. TIFFGetMode(tif)
  336.     TIFF *tif;
  337. {
  338.     return (tif->tif_mode);
  339. }
  340.  
  341. /*
  342.  * Return nonzero if file is organized in
  343.  * tiles; zero if organized as strips.
  344.  */
  345. int
  346. TIFFIsTiled(tif)
  347.     TIFF *tif;
  348. {
  349.     return (isTiled(tif));
  350. }
  351.  
  352. /*
  353.  * Return current row being read/written.
  354.  */
  355. long
  356. TIFFCurrentRow(tif)
  357.     TIFF *tif;
  358. {
  359.     return (tif->tif_row);
  360. }
  361.  
  362. /*
  363.  * Return index of the current directory.
  364.  */
  365. int
  366. TIFFCurrentDirectory(tif)
  367.     TIFF *tif;
  368. {
  369.     return (tif->tif_curdir);
  370. }
  371.  
  372. /*
  373.  * Return current strip.
  374.  */
  375. int
  376. TIFFCurrentStrip(tif)
  377.     TIFF *tif;
  378. {
  379.     return (tif->tif_curstrip);
  380. }
  381.  
  382. /*
  383.  * Return current tile.
  384.  */
  385. int
  386. TIFFCurrentTile(tif)
  387.     TIFF *tif;
  388. {
  389.     return (tif->tif_curtile);
  390. }
  391.